

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <getopt.h>

#include <sys/socket.h>
#include <sys/time.h>
#include <pthread.h>

#include <arpa/inet.h>
#include "test.h"

int connect_tcpserver(const char *ip, unsigned short port);

int send_msg(int connfd, char *msg, int length)
{

    int res = send(connfd, msg, length, 0);
    if (res < 0)
    {
        perror("send");
        exit(1);
    }
    return res;
}

int recv_msg(int connfd, char *msg, int length)
{

    int res = recv(connfd, msg, length, 0);
    // LOG("res: %s\n", msg);
    if (res < 0)
    {
        perror("recv");
        exit(1);
    }
    return res;
}

void equals(char *pattern, char *result, char *casename)
{

    if (strcmp(pattern, result) == 0)
    {
        // printf("[PASS]: %s\n", casename);
    }
    else
    {
        printf("[FAILED]: %s, '%s' != '%s'\n", casename, pattern, result);
    }
}

void test_case(int connfd, char *msg, char *pattern, char *casename)
{

    if (!msg || !pattern || !casename)
        return;

    send_msg(connfd, msg, strlen(msg));
    // LOG("send: %s\n", msg);

    char result[MAX_MAS_LENGTH] = {0};
    recv_msg(connfd, result, MAX_MAS_LENGTH);

    // LOG("recv: %s\n", result);
    equals(pattern, result, casename);
}

void *rbtree_del(void *num)
{
    int connfd = connect_tcpserver(IP, PORT);

    int count = *(int *)num;

    int i = 0;

    for (i = count - PER_THREAD_COUNT; i < count; i++)
    {

        char cmd[128] = {0};

        snprintf(cmd, 128, "RDEL Name%d\x03", i);
        test_case(connfd, cmd, "RDEL SUCCESS\r\n", "DELCase");

        snprintf(cmd, 128, "HDEL Name%d\x03", i);
        test_case(connfd, cmd, "HDEL SUCCESS\r\n", "DELCase");

        snprintf(cmd, 128, "SDEL Name%d\x03", i);
        test_case(connfd, cmd, "SDEL SUCCESS\r\n", "DELCase");
    }
}

int connect_tcpserver(const char *ip, unsigned short port)
{

    int connfd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in tcpserver_addr;
    memset(&tcpserver_addr, 0, sizeof(struct sockaddr_in));

    tcpserver_addr.sin_family = AF_INET;
    tcpserver_addr.sin_addr.s_addr = inet_addr(ip);
    tcpserver_addr.sin_port = htons(port);

    int ret = connect(connfd, (struct sockaddr *)&tcpserver_addr, sizeof(struct sockaddr_in));
    if (ret)
    {
        perror("connect");
        return -1;
    }

    return connfd;
}

// ./testcase -s 192.168.243.131 -p 9096 -m 1
int main(int argc, char *argv[])
{
    pthread_t thread[THREAD_NUM] = {0};
    int count[THREAD_NUM] = {0};

     struct timeval tv_begin;
    gettimeofday(&tv_begin, NULL);
    for (int i = 0; i < THREAD_NUM; i++)
    {
        count[i] = PER_THREAD_COUNT * (i + 1);
        pthread_create(&thread[i], NULL, rbtree_del, &count[i]);
    }

    for (int i = 0; i < THREAD_NUM; i++)
    {
        pthread_join(thread[i], NULL);
    }

       struct timeval tv_end;
    gettimeofday(&tv_end, NULL);

    int time_used = TIME_SUB_MS(tv_end, tv_begin);

    for (int i = 0; i < THREAD_NUM; i++)
    {
        printf("count[%d]: %d\n", i, count[i]);
    }

   int num = THREAD_NUM * PER_THREAD_COUNT;
    printf("三个引擎各删除%d条数据\n", num);

    printf("kvstore del: time_used: %d ms, qps: %d\n", time_used, 3 * PER_THREAD_COUNT * THREAD_NUM * 1000 / time_used);
}
